package edu.erpan.bl.bean.administracion;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import javax.persistence.Query;

import edu.erpan.bl.entities.administracion.Genero;
import edu.erpan.bl.entities.administracion.Modulo;
import edu.erpan.bl.entities.administracion.Persona;
import edu.erpan.bl.entities.administracion.Rol;
import edu.erpan.bl.entities.administracion.TipoIdentificacion;
import edu.erpan.bl.entities.administracion.Usuario;
import edu.erpan.util.entityManager.GenericEntityManager;
import edu.erpan.util.entityManager.exceptions.PersistException;
import edu.erpan.util.entityManager.exceptions.QueryException;

/**
 * Session Bean implementation class UsuarioBean
 */
@Stateful
@LocalBean
public class UsuarioBean extends GenericEntityManager<Usuario> implements UsuarioBeanRemote {

    /**
     * Default constructor. 
     */
    public UsuarioBean() {
        // TODO Auto-generated constructor stub
    	super(Usuario.class);
    }

	/* (non-Javadoc)
	 * @see edu.erpan.bl.bean.administracion.UsuarioBeanRemote#consultarUsuario(java.lang.String, java.lang.String)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public Usuario consultarUsuario(String login, String password) throws QueryException {
		// TODO Auto-generated method stub
		StringBuffer stringQuery=new StringBuffer("SELECT usuario from ")
			.append(Usuario.class.getName())
			.append(" usuario WHERE usuario.login=? ");
		
		if(password!=null){
			stringQuery.append("and usuario.password = ? ");
		}
		
		Query query=getEntityManager().createQuery(stringQuery.toString());
		
		query.setParameter(1, login);
		if(password!=null){
			query.setParameter(2, password);
		}
		
		List<Usuario> usuarios=query.getResultList();
		
		Usuario usuario=null;
		
		if(usuarios!=null&&!usuarios.isEmpty()){
			usuario=usuarios.get(0);
		}
		
		return usuario;
	}

	/* (non-Javadoc)
	 * @see edu.erpan.bl.bean.administracion.UsuarioBeanRemote#consultarRolesUsuario(edu.erpan.bl.entities.administracion.Usuario)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<Rol> consultarRolesUsuario(Usuario usuario) throws QueryException {
		// TODO Auto-generated method stub
		String stringQuery="SELECT rol FROM "+Usuario.class.getName()+" user "
				+ " INNER JOIN user.roles rol "
				+ " WHERE user.idusuario ="+usuario.getIdusuario()
				+" ORDER BY rol.nombre asc";
		
		Query query =getEntityManager().createQuery(stringQuery);
		return query.getResultList();
	}

	/* (non-Javadoc)
	 * @see edu.erpan.bl.bean.administracion.UsuarioBeanRemote#consultarModulos(edu.erpan.bl.entities.administracion.Usuario, edu.erpan.bl.entities.administracion.Rol)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public Rol consultarRol(Rol rol) throws QueryException {
		String stringQuery="SELECT rol FROM "+Rol.class.getName()+" rol WHERE rol.idrol="+rol.getIdrol();
		Query query =getEntityManager().createQuery(stringQuery);
		List<Rol> resultado=query.getResultList();
		if(resultado.isEmpty()){
			return null;
		}else{
			return (Rol) resultado.get(0);
		}
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public Modulo consultarModulo(Modulo modulo) throws QueryException {
		// TODO Auto-generated method stub
		String stringQuery="SELECT modulo FROM "+Modulo.class.getName()+" modulo WHERE modulo.idmodulo = "+modulo.getIdmodulo();
		Query query =getEntityManager().createQuery(stringQuery);
		List<Modulo> resultado=query.getResultList();
		if(resultado.isEmpty()){
			return null;
		}else{
			return (Modulo) resultado.get(0);
		}
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<Modulo> consultarModulosPorRol(List<Rol> roles) throws QueryException {
		StringBuffer stringQuery=new StringBuffer("SELECT DISTINCT modulo FROM ")
			.append(Modulo.class.getName()).append(" modulo ")
			.append("INNER JOIN modulo.roles rol ")
			.append("WHERE rol.idrol in ({0}) ")
			.append("ORDER BY modulo.orden asc ");

		String idRoles="";
		for (Rol rol : roles) {
			idRoles+=rol.getIdrol()+",";
		}
		
		if (idRoles.endsWith(",")) {
			idRoles=idRoles.substring(0,idRoles.length()-1);
		}
		
		String filter= stringQuery.toString().replace("{0}", idRoles);
		
		Query query =getEntityManager().createQuery(filter);
		
		List<Modulo> resultado=query.getResultList();
		return resultado;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<Persona> consultarPersonas(Boolean activo) throws QueryException{
		StringBuffer stringBuffer=new StringBuffer("SELECT persona FROM "+Persona.class.getName()+" persona ");
		
		if(activo!=null){
			stringBuffer.append("WHERE persona.activo = :activo ");
		}
		
		stringBuffer.append("ORDER BY persona.primerApellido ASC, persona.segundoApellido ASC, persona.nombres ASC");
		
		String queryString=stringBuffer.toString();
		
		Query query=getEntityManager().createQuery(queryString);
		
		if(activo!=null){
			query.setParameter("activo", activo);
		}
		
		List<Persona>personas=new ArrayList<Persona>(0);
		try{
			personas=query.getResultList();
		}catch (Exception e) {
			throw new QueryException(e);
		}
		return personas;		
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Usuario> consultarUsuariosPersonas(Persona persona)
			throws QueryException {
		StringBuffer stringQuery=new StringBuffer("SELECT usuario from ")
			.append(Usuario.class.getName())
			.append(" usuario ")
			.append("INNER JOIN usuario.persona persona ")
			.append("WHERE persona.idpersona = :codigoPersona");
		Query query=getEntityManager().createQuery(stringQuery.toString());
		
		query.setParameter("codigoPersona", persona.getIdpersona());
		
		List<Usuario> usuarios=new ArrayList<Usuario>(0);
		try{
			usuarios=query.getResultList();
		}catch (Exception e) {
			throw new QueryException(e);
		}
		
		return usuarios;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Persona consultarPersona(Persona persona) throws QueryException {
		
		Persona personaRetorno=null;
		try{
			StringBuffer stringQuery=new StringBuffer("SELECT persona from ")
				.append(Persona.class.getName())
				.append(" persona ");
			
			int contadorCondiciones=0;
			StringBuffer stringWhere=new StringBuffer("WHERE ");
			if(persona.getIdpersona()>0){
				stringWhere.append("persona.idpersona = :codigoPersona ");
				contadorCondiciones++;
			}
			
			if(persona.getTipoIdentificacion()!=null&&persona.getTipoIdentificacion().getIdtipoIdentificacion()>0){
				if(contadorCondiciones>0){
					stringWhere.append("AND ");
				}
				
				stringWhere.append("persona.tipoIdentificacion.idtipoIdentificacion = :idtipoIdentificacion ");
				contadorCondiciones++;
			}
			
			if(persona.getNumeroIdentificacion()!=null&&!persona.getNumeroIdentificacion().trim().isEmpty()){
				if(contadorCondiciones>0){
					stringWhere.append("AND ");
				}
				stringWhere.append("persona.numeroIdentificacion = :numeroIdentificacion ");
				contadorCondiciones++;
			}
			
			stringQuery.append(stringWhere);
			
			Query query=getEntityManager().createQuery(stringQuery.toString());

			if(persona.getIdpersona()>0){
				query.setParameter("codigoPersona", persona.getIdpersona());
			}
			
			if(persona.getTipoIdentificacion()!=null&&persona.getTipoIdentificacion().getIdtipoIdentificacion()>0){
				query.setParameter("idtipoIdentificacion", persona.getTipoIdentificacion().getIdtipoIdentificacion());
			}
			
			if(persona.getNumeroIdentificacion()!=null&&!persona.getNumeroIdentificacion().trim().isEmpty()){
				query.setParameter("numeroIdentificacion", persona.getNumeroIdentificacion().trim() );
			}
			
			List<Persona>personas=query.getResultList();
			if(personas!=null&&!personas.isEmpty()){
				personaRetorno=personas.get(0);
			}
		}catch (Exception e) {
			throw new QueryException(e);
		}
		return personaRetorno;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Persona consultarPersonaPorIdentificacion(Persona persona) throws QueryException {
		List<Persona>personas=null;
		try{
			StringBuffer stringQuery=new StringBuffer("select persona ")
				.append("from ").append(Persona.class.getCanonicalName()).append(" persona ")
				.append("where ")
				.append("persona.numeroIdentificacion = :numeroIdentificacion ")
				.append("and persona.tipoIdentificacion.idtipoIdentificacion = :idTipoId ")
				.append(persona.getIdpersona()>0?"and persona.idpersona <> :idPersona ":"")
				.append("ORDER BY persona.primerApellido ASC, persona.segundoApellido ASC, persona.nombres ASC");
			
			Query query=this.getEntityManager().createQuery(stringQuery.toString());
			query.setParameter("numeroIdentificacion", persona.getNumeroIdentificacion());
			query.setParameter("idTipoId", persona.getTipoIdentificacion().getIdtipoIdentificacion());
			if(persona.getIdpersona()>0){
				query.setParameter("idPersona", persona.getIdpersona());
			}
			personas=query.getResultList();
			if(personas.size()>0){
				persona=personas.get(0);
			}else{
				return null;
			}
		}catch (Exception e) {
			throw new QueryException(e);
		}	
		return persona;
	}
	
	@Override
	public void guardarPersona(Persona persona) throws PersistException {
		try{
			this.getEntityManager().merge(persona);
		}catch (Exception e) {
    		throw new PersistException(e);
		}		
	}

	@Override
	public void editarPersona(Persona persona) throws PersistException {
		try{
			this.getEntityManager().merge(persona);
		}catch (Exception e) {
    		throw new PersistException(e);
		}
	}

	@Override
	public void guardarUsuario(Usuario usuario) throws PersistException {
		try{
			this.getEntityManager().merge(usuario);
		}catch (Exception e) {
    		throw new PersistException(e);
		}		
	}

	@Override
	public void editarUsuario(Usuario usuario) throws PersistException {
		try{
			this.getEntityManager().merge(usuario);
		}catch (Exception e) {
    		throw new PersistException(e);
		}		
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<TipoIdentificacion> consultarTiposIdentificacion()
			throws QueryException {
		List<TipoIdentificacion> tiposIdentificacion=new ArrayList<TipoIdentificacion>(0);
		try{
			StringBuffer stringQuery=new StringBuffer("SELECT tipoId from ")
				.append(TipoIdentificacion.class.getName())
				.append(" tipoId ");
			Query query=getEntityManager().createQuery(stringQuery.toString());
			
			tiposIdentificacion=query.getResultList();
		}catch (Exception e) {
			throw new QueryException(e);
		}
		return tiposIdentificacion;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Genero> consultarGeneros() throws QueryException {
		List<Genero> generos=new ArrayList<Genero>(0);
		try{
			StringBuffer stringQuery=new StringBuffer("SELECT genero from ")
				.append(Genero.class.getName())
				.append(" genero ");
			Query query=getEntityManager().createQuery(stringQuery.toString());
			
			generos=query.getResultList();
		}catch (Exception e) {
			throw new QueryException(e);
		}
		return generos;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Rol> consultarRoles() throws QueryException {
		List<Rol> resultado=new ArrayList<Rol>(0);
		try{
			String stringQuery="SELECT rol FROM "+Rol.class.getName()+" rol ";
			Query query =getEntityManager().createQuery(stringQuery);
			resultado=query.getResultList();
		}catch (Exception e) {
			throw new QueryException(e);
		}
		return resultado;
	}
}
